package com.xmlt.core.template.tags;

import java.util.ArrayList;
import java.util.List;

import javax.xml.xpath.XPathExpressionException;


import ognl.OgnlException;

import org.w3c.dom.Element;

import com.xmlt.core.template.TemplateException;
import com.xmlt.core.template.TemplateSection;
import com.xmlt.core.template.Utils;
import com.xmlt.core.template.expression.ExpressionFactory;
import com.xmlt.core.template.instance.AbstractInstance;
import com.xmlt.core.template.instance.MultiInstance;

public class LoopTag extends TemplateSectionElement {
	private TemplateSection loopExpression;
	private TemplateSection bodySection;

	public LoopTag(Element el) throws TemplateException {
		try {
			Element body = (Element) Utils.evaluateXPath(el, "body").item(0);
			if (body != null)
				bodySection = new TemplateSection("body", body);
		} catch (XPathExpressionException e) {
			throw new TemplateException(e);
		}
	}

	@Override
	public void setParameter(String name, Element el) throws TemplateException {
		if (!"loopExpression".equals(name))
			super.setParameter(name, el);
		else {
			loopExpression = new TemplateSection("body", el);
		}
	}

	@Override
	public List<TemplateSectionElement> generateTags(AbstractInstance instance) throws OgnlException {
		List<TemplateSectionElement> l = new ArrayList<TemplateSectionElement>();
		String loopExpr = loopExpression.generate(instance);
		Object o = ExpressionFactory.getExpression(loopExpr).evaluate(instance, false);
		if (o instanceof MultiInstance) {
			List<AbstractInstance> children = ((MultiInstance) o).getChildren();
			for (AbstractInstance ai : children) {
				for (TemplateSectionElement tse : bodySection.getTags()) {
					l.addAll(tse.generateTags(ai));
				}
			}
		}
		return l;
	}
	
	public AbstractInstance getLoopInstance(AbstractInstance instance) throws OgnlException {
		String loopExpr = loopExpression.generate(instance);
		Object o = ExpressionFactory.getExpression(loopExpr).evaluate(instance, false);
		if (o instanceof AbstractInstance) {
			return (AbstractInstance) o;
		}
		return null;
	}

}
